﻿using System;
using Amazon.SimpleNotificationService.Model;
using NUnit.Framework;
using Rhino.Mocks;
using ShuttleBus;
using ShuttleBus.Transports.AmazonSqs;
using ShuttleBus.Transports.AmazonSqs.Clients;
using Tests.Transports.AmazonSqs.Fakes;
using Subscription = ShuttleBus.AdminMessages.Subscription;

namespace Tests.Transports.AmazonSqs.SubscriptionRepositoryTests
{
    public partial class SubscriptionRepositoryTests
    {
        [TestFixture]
        public class WhenAddingSubscribers
        {
            private SnsSubscriptionRepository _repository;
            private ISnsClient _snsClient;
            private ISqsClient _sqsClient;
            private string _myQueueName;

            [SetUp]
            public void SetUp()
            {
                _snsClient = MockRepository.GenerateMock<ISnsClient>();
                _sqsClient = MockRepository.GenerateMock<ISqsClient>();

                _myQueueName = "some_queue";
                _repository = new SnsSubscriptionRepository(_snsClient, _sqsClient, new Uri("sqs://" + _myQueueName));
            }

            [TearDown]
            public void TearDown()
            {
                _snsClient.VerifyAllExpectations();
                _sqsClient.VerifyAllExpectations();
            }

            [Test]
            public void No_Matching_Topics_Exist_Creates_Topic_And_Adds_Subscription()
            {
                var subscription = new AddSubscriptionMessage {MessageType = typeof (MyMessage).AssemblyQualifiedName, Sender = null};
                var queueArn = "arn:aws:sqs:us-east-1:123456789012:some_queue";

                _sqsClient.Expect(s => s.GetQueueArn(_myQueueName)).Return(queueArn);

                var topic = new Topic { TopicArn = "arn:aws:sns:us-east-1:123456789012:mymessage" };

                _snsClient.Expect(s => s.QueryTopics("MyMessage")).Return(new Topic[0]);
                _snsClient.Expect(s => s.Create("MyMessage")).Return(topic);
                _snsClient.Expect(s => s.Subscribe(queueArn, new[] {topic}));

                _repository.Add(subscription);
            }

            [Test]
            public void Topic_Already_Exists_Adds_Subscription()
            {
                var subscription = new AddSubscriptionMessage { MessageType = typeof(MyMessage).AssemblyQualifiedName, Sender = null };

                var queueArn = "arn:aws:sqs:us-east-1:123456789012:some_queue";
                var topic = new Topic { TopicArn = "arn:aws:sns:us-east-1:123456789012:mymessage" };

                _sqsClient.Expect(s => s.GetQueueArn(_myQueueName)).Return(queueArn);
                _snsClient.Expect(t => t.QueryTopics("MyMessage")).Return(new[] { topic });
                _snsClient.Expect(t => t.Subscribe(queueArn, new[] {topic}));
                
                _repository.Add(subscription);
            }
        }
    }
}